<template>
  <div>
    <BasicTable @register="registerDeviceTable">
      <template #headerTop>
        <Alert v-if="checkedKeys.length > 0" type="info" show-icon class="relative">
          <template #message>
            <div>
              <span>已选中{{ checkedKeys.length }}条记录</span>
              <div class="absolute top-4px right-10px">
                <Tooltip title="分配客户">
                  <a-button type="text" @click="handleSelectedAssign">
                    <Icon :icon="ICON.ASSIGN" color="#0960bd" />
                  </a-button>
                </Tooltip>
                <Tooltip title="删除">
                  <a-button type="text" @click="handleSelectedDelete">
                    <Icon :icon="ICON.DELETE" color="#0960bd" />
                  </a-button>
                </Tooltip>
              </div>
            </div>
          </template>
        </Alert>
      </template>
      <!-- 操作按钮 -->
      <template #toolbar v-if="hasPermission(RoleEnum.TENANT_ADMIN)">
        <Dropdown
          :trigger="['click']"
          :dropMenuList="[
            {
              text: '添加设备',
              icon: ICON.ADDENTITY,
              event: '',
              onClick: () => {
                openAddModal(true, 'test');
              },
            },
            {
              text: '导入设备',
              icon: ICON.IMPORTENTITY,
              event: '',
              onClick: () => {
                openUploadModal(true, 'test');
              },
            },
          ]"
        >
          <a-button type="primary">添加设备 </a-button>
        </Dropdown>
      </template>
      <template #bodyCell="{ column, record }">
        <template v-if="hasPermission(RoleEnum.TENANT_ADMIN) && column.key === 'action'">
          <TableAction
            :stopButtonPropagation="true"
            :actions="[
              {
                icon: ICON.EDIT,
                tooltip: {
                  title: '编辑',
                  placement: 'top',
                },
                onClick: handleEdit.bind(null, record),
              },
              {
                icon: ICON.CHECK,
                tooltip: {
                  title: '查看',
                  placement: 'top',
                },
                onClick: handleDetail.bind(null, record),
              },
              {
                icon: ICON.DELETE,
                onClick: handleDelete.bind(null, record),
              },
            ]"
            :dropDownActions="[
              {
                icon: ICON.PUBLIC,
                label: '公开',
                disabled: record.customerIsPublic || record.customerTitle,
                onClick: handlePublic.bind(null, record),
              },
              {
                icon: ICON.ASSIGN,
                label: '分配给客户',
                disabled: record.customerTitle,
                onClick: openCustomerModal.bind(null, true, { record, key: 'customer' }),
              },
              {
                icon: ICON.UNASSIGN,
                label: '取消分配给客户',
                disabled: !record.customerTitle || record.customerIsPublic,
                onClick: handleCancel.bind(null, record),
              },
              {
                icon: ICON.PRIVATE,
                label: '私有',
                disabled: !record.customerIsPublic,
                onClick: handlePrivate.bind(null, record),
              },
              {
                icon: ICON.SECURITY,
                label: '管理凭据',
                onClick: openCertificateModal.bind(null, true, { record, key: 'token' }),
              },
            ]"
          />
        </template>
        <template v-if="hasPermission(RoleEnum.CUSTOMER_USER) && column.key === 'action'">
          <TableAction
            :stopButtonPropagation="true"
            :actions="[
              {
                icon: ICON.CHECK,
                tooltip: {
                  title: '查看',
                  placement: 'top',
                },
                onClick: handleDetail.bind(null, record),
              },
              {
                icon: ICON.SECURITY,
                tooltip: {
                  title: '管理凭据',
                  placement: 'top',
                },
                onClick: openCertificateModal.bind(null, true, { record, key: 'token' }),
              },
            ]"
          />
        </template>
      </template>
    </BasicTable>
    <PublicDrawer
      @register="registerDrawer"
      @update-desc-data="handleUpdateDescData"
      :show-tabs="
        hasPermission(RoleEnum.CUSTOMER_USER)
          ? ['detail', 'attribute', 'telemetry', 'alarm', 'event', 'association']
          : [
              'detail',
              'attribute',
              'telemetry',
              'alarm',
              'event',
              'association',
              'auditLogs',
              'version',
            ]
      "
    />
    <CustomerModal @register="registerCustomerModal" @success="handleSuccess" />
    <CertificateModal @register="registerCertificateModal" @success="handleSuccess" />
    <AddDeviceModal @register="registerAddModal" @success="handleSuccess" />
    <UploadDeviceModal @register="registerUploadModal" @success="handleSuccess" />
    <EditDeviceModal @register="registerEditModal" @success="handleSuccess" />
  </div>
</template>

<script setup lang="ts">
  import { BasicTable, useTable, TableAction } from '/@/components/Table';
  import { deviceTableSchema, searchSchema } from './device.data';
  import PublicDrawer from '/@/components/thingsborad/sharedComponents/modules/PublicDrawer/index.vue';
  import { ENTITY_TYPE } from '/@/components/thingsborad/sharedComponents/modules/PublicDrawer/index.data';
  import Icon from '/@/components/Icon';
  import { ICON } from '/@/enums/iconEnum';
  import { useDrawer } from '/@/components/Drawer';
  import { useModal } from '/@/components/Modal';
  import { useMessage } from '/@/hooks/web/useMessage';
  import AddDeviceModal from './modal/AddDeviceModal.vue';
  import UploadDeviceModal from './modal/UploadDeviceModal.vue';
  import { Dropdown } from '/@/components/Dropdown';
  import CustomerModal from './modal/CustomerModal.vue';
  import CertificateModal from './modal/CertificateModal.vue';
  import EditDeviceModal from './modal/EditDeviceModal.vue';
  import { onMounted, ref } from 'vue';
  import { Alert, Tooltip } from 'ant-design-vue';
  import {
    getEntityDeviceList,
    unassignCustomer,
    assignCustomer,
    setPublic,
    deleteEntity,
    updateDevice,
    createDevice,
    saveDeviceWithCredentials,
    updateDeviceCredentials,
    getEntityListByCustomerId,
    getDeviceInfo,
    getEntityListByEdgeId,
    getCustomerEntityDeviceList,
  } from '/@/api/thingsborad/entity/entity';
  import {
    deviceTableItem,
    addBasicDeviceParams,
    addDeviceWithCredentialsParams,
    deviceCredentialsInfo,
  } from '/@/api/thingsborad/entity/model/entityModel';
  import { detailSchema } from './device.data';
  import { useRoute } from 'vue-router';
  import { tableFormStyleSetting, tableStyleSetting } from '/@/settings/thingsBoardDesign';
  import { useUserStore } from '/@/store/modules/user';
  import { RoleEnum } from '/@/enums/roleEnum';
  import { usePermission } from '/@/hooks/web/usePermission';
  const { hasPermission } = usePermission();

  const checkedKeys = ref<any>([]);
  const route = useRoute();
  const userStore = useUserStore();

  const [registerDeviceTable, { reload, setProps }] = useTable({
    title: '设备',
    columns: deviceTableSchema,
    ...tableStyleSetting,
    immediate: false,
    afterFetch: (res) => {
      let list: deviceTableItem[] = [];
      res.length != 0
        ? res.forEach((item: any) => {
            let tableItem: deviceTableItem = {
              createdTime: item.createdTime,
              name: item.name,
              deviceProfileName: item.deviceProfileName,
              label: item.label,
              active: item.active,
              customerTitle: item.customerTitle,
              customerIsPublic: item.customerIsPublic,
              isGateway: item?.additionalInfo?.gateway,
              id: item.id.id,
              deviceProfileId: item.deviceProfileId,
              additionalInfo: item.additionalInfo,
            };
            list.push(tableItem);
          })
        : null;
      return list;
    },
    formConfig: {
      layout: 'horizontal',
      schemas: searchSchema,
      showAdvancedButton: false,
      ...tableFormStyleSetting,
      actionColOptions: {
        md: { span: 8, offset: 16 },
        lg: { span: 6, offset: 0 },
        xl: { span: 4, offset: 8 },
        xxl: { span: 4, offset: 8 },
      },
    },
    fetchSetting: {
      pageField: 'page',
      sizeField: 'pageSize',
      listField: 'data',
      totalField: 'totalElements',
    },
    rowKey: 'id',
    rowSelection: {
      type: 'checkbox',
      selectedRowKeys: checkedKeys,
      onSelect: onSelect,
      onSelectAll: onSelectAll,
    },
  });
  const [registerDrawer, { openDrawer }] = useDrawer();
  const [registerCustomerModal, { openModal: openCustomerModal }] = useModal();
  const [registerCertificateModal, { openModal: openCertificateModal }] = useModal();
  const [registerAddModal, { openModal: openAddModal }] = useModal();
  const [registerUploadModal, { openModal: openUploadModal }] = useModal();
  const [registerEditModal, { openModal: openEditModal }] = useModal();
  const { createConfirm } = useMessage();
  // 编辑
  function handleEdit(record: Recordable) {
    openEditModal(true, { record });
  }
  // 公开
  function handlePublic(record: Recordable) {
    createConfirm({
      iconType: 'info',
      title: `确定要将设备${record.name}设为公开吗？`,
      content: '确认后，设备及其所有数据将被设为公开并可被其他人访问。',
      onOk: async () => {
        await setPublic(record.id);
        reload();
      },
    });
  }
  // 私有
  function handlePrivate(record: Recordable) {
    createConfirm({
      iconType: 'info',
      title: `确定要将设备${record.name}设为私有吗？`,
      content: '确认后，设备及其所有数据将被设为私有，不被其他人访问。',
      onOk: async () => {
        await unassignCustomer({ entityType: 'device', id: record.id });
        reload();
      },
    });
  }
  // 取消分配
  function handleCancel(record: Recordable) {
    createConfirm({
      iconType: 'info',
      title: `确定要取消分配设备${record.name}吗？`,
      content: '确认后，设备将被取消分配，客户将无法访问。',
      onOk: async () => {
        await unassignCustomer({ entityType: 'device', id: record.id });
        reload();
      },
    });
  }
  // 删除
  function handleDelete(record: Recordable) {
    createConfirm({
      iconType: 'info',
      title: `确定要删除设备的${record.name}吗？`,
      content: '请注意：确认后，设备及其所有相关数据将不可恢复。',
      onOk: async () => {
        await deleteEntity({ entityType: 'device', entityId: record.id });
        await reload();
      },
    });
  }
  // 详情
  function handleDetail(record: Recordable) {
    openDrawer(true, {
      entityType: ENTITY_TYPE.DEVICE,
      entityId: record.id,
      title: record.name,
      api: getDeviceInfo,
      detailSchema: detailSchema,
      params: record.id,
    });
  }
  // 抽屉详情数据更改
  function handleUpdateDescData(value: Recordable) {
    value.createdTime = value.createdTime;
    value.name = value.name;
    value.deviceConfiguration = value.deviceProfileName;
    value.label = value.label;
    value.state = value.active;
    value.customer = value.customerTitle;
    value.isOpen = value.customerIsPublic;
    value.isGateway = value.additionalInfo?.gateway;
  }
  // 多选
  function onSelect(record: Recordable, selected: boolean) {
    if (selected) {
      checkedKeys.value = [...checkedKeys.value, record.id];
    } else {
      checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id);
    }
  }
  // 全选
  function onSelectAll(selected: boolean, _selectedRows: Recordable[], changeRows: Recordable[]) {
    const changeIds = changeRows.map((item) => item.id);
    if (selected) {
      checkedKeys.value = [...checkedKeys.value, ...changeIds];
    } else {
      checkedKeys.value = checkedKeys.value.filter((id) => {
        return !changeIds.includes(id);
      });
    }
  }
  // 多选分配
  function handleSelectedAssign() {
    openCustomerModal(true, { checkedKeys, key: 'selected' });
  }
  // 多选删除
  function handleSelectedDelete() {
    createConfirm({
      iconType: 'info',
      title: `确定要删除${checkedKeys.value.length}个设备吗？`,
      content: '请注意：确认后，设备及其所有相关数据将不可恢复。',
      onOk: async () => {
        setProps({ loading: true });
        for (const item of checkedKeys.value) {
          await deleteEntity({ entityType: 'device', entityId: item });
        }
        reload();
        checkedKeys.value = [];
      },
    });
  }

  async function handleSuccess(obj: any) {
    console.log();
    switch (obj.key) {
      case 'selectedAssign':
        setProps({ loading: true });
        const promises = obj.values.checkedKeys.map((item) =>
          assignCustomer({
            customerId: obj.values.customerId,
            entityType: 'device',
            entityId: item,
          }),
        );
        await Promise.all(promises);
        reload();
        checkedKeys.value = [];
        break;
      case 'assign':
        await assignCustomer({
          customerId: obj.values.customerId,
          entityType: 'device',
          entityId: obj.values.deviceId,
        });
        reload();
        break;
      case 'edit':
        obj.record.deviceProfileId =
          typeof obj.values.deviceProfileName != 'object'
            ? obj.record.deviceProfileId
            : JSON.parse(obj.values.deviceProfileName);
        obj.record.name = obj.values.name;
        obj.values.software
          ? (obj.record.software = {
              entityType: 'OTA_PACKAGE',
              id: obj.values.software,
            })
          : '';
        obj.values.firmware
          ? (obj.record.firmware = {
              entityType: 'OTA_PACKAGE',
              id: obj.values.firmware,
            })
          : '';
        obj.record.label = obj.values.label;
        obj.record.additionalInfo = {
          description: obj.values.remark,
          gateway: Boolean(obj.values.isGateway),
          overwriteActivityTime: Boolean(obj.values.isCover),
        };
        await updateDevice(obj.record);
        reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
        break;
      case 'basicAdd':
        let addBasicDeviceParams: addBasicDeviceParams = {
          name: obj.values.name,
          label: obj.values?.label,
          deviceProfileId: JSON.parse(obj.values?.deviceConfiguration),
          customerId: obj.values.customer
            ? { entityType: 'CUSTOMER', id: obj.values.customer }
            : null,
          additionalInfo: {
            description: obj.values?.remark,
            gateway: Boolean(obj.values?.isGateway),
            overwriteActivityTime: Boolean(obj.values?.isCover),
          },
        };

        await createDevice(addBasicDeviceParams);
        reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
        break;
      case 'addWithCredentials':
        let addDeviceWithCredentialsParams: addDeviceWithCredentialsParams;
        if (obj.values?.credentialsType == 'Access Token') {
          addDeviceWithCredentialsParams = {
            device: {
              name: obj.values?.name,
              label: obj.values?.label,
              deviceProfileId: JSON.parse(obj.values?.deviceConfiguration),
              customerId: obj.values.customer
                ? { entityType: 'CUSTOMER', id: obj.values.customer }
                : null,
              additionalInfo: {
                description: obj.values?.remark,
                gateway: Boolean(obj.values?.isGateway),
                overwriteActivityTime: Boolean(obj.values?.isCover),
              },
            },
            credentials: {
              credentialsType: 'ACCESS_TOKEN',
              credentialsId: obj.values?.token,
              credentialsValue: '',
            },
          };
        } else if (obj.values?.credentialsType == 'X.509') {
          addDeviceWithCredentialsParams = {
            device: {
              name: obj.values?.name,
              label: obj.values?.label,
              deviceProfileId: obj.values?.deviceProfileId,
              customerId: obj.values.customer
                ? { entityType: 'CUSTOMER', id: obj.values.customer }
                : null,
              additionalInfo: {
                description: obj.values?.remark,
                gateway: Boolean(obj.values?.isGateway),
                overwriteActivityTime: Boolean(obj.values?.isCover),
              },
            },
            credentials: {
              credentialsType: 'X509_CERTIFICATE',
              credentialsId: '',
              credentialsValue: obj.values?.certificate,
            },
          };
        } else {
          let credentialsValue = JSON.stringify({
            clientId: obj.values?.id,
            userName: obj.values?.username,
            password: obj.values?.password,
          });
          addDeviceWithCredentialsParams = {
            device: {
              name: obj.values?.name,
              label: obj.values?.label,
              deviceProfileId: obj.values?.deviceProfileId,
              customerId: obj.values.customer
                ? { entityType: 'CUSTOMER', id: obj.values.customer }
                : null,
              additionalInfo: {
                description: obj.values?.remark,
                gateway: Boolean(obj.values?.isGateway),
                overwriteActivityTime: Boolean(obj.values?.isCover),
              },
            },
            credentials: {
              credentialsType: 'MQTT_BASIC',
              credentialsId: '',
              credentialsValue: credentialsValue,
            },
          };
        }
        await saveDeviceWithCredentials(addDeviceWithCredentialsParams);
        reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
        break;
      case 'credentials':
        let params: deviceCredentialsInfo = obj.credentialsResponse;
        obj?.value?.token ? (params.credentialsId = obj.value?.token) : null;
        obj?.value?.certificate ? (params.credentialsValue = obj.value?.certificate) : null;
        obj?.value?.id
          ? (params.credentialsValue = JSON.stringify({
              clientId: obj.value?.id,
              userName: obj.value?.username,
              password: obj.value?.password,
            }))
          : null;
        params.credentialsType = obj.credentialsType;

        await updateDeviceCredentials(params);
        reload();
        break;
      case 'import':
        reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
    }
  }

  function getParams(val: Recordable) {
    return {
      page: val.page - 1,
      pageSize: val.pageSize,
      sortOrder: val.order == 'ascend' ? 'ASC' : 'DESC',
      sortProperty: val.field,
      textSearch: val.textSearch,
      deviceProfileId: val.deviceProfileId,
      active: val.state,
    };
  }

  onMounted(async () => {
    const roleList = userStore.getRoleList;
    const { customerId } = userStore.getUserInfo;

    if (roleList.includes(RoleEnum.TENANT_ADMIN)) {
      if (Boolean(route.params.key)) {
        switch (route.params.key) {
          case '客户':
            setProps({
              api: getEntityListByCustomerId,
              beforeFetch: (val) => {
                return Object.assign(getParams(val), {
                  urlParams: {
                    infosType: 'deviceInfos',
                    customerId: route.params.id,
                  },
                });
              },
              title: `${route.params.name}:设备`,
            });
            reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
            break;
          case '边缘实例':
            setProps({
              api: getEntityListByEdgeId,
              beforeFetch: (val) => {
                return Object.assign(getParams(val), {
                  urlParams: {
                    edgeId: route.params.id,
                    infosType: 'devices',
                  },
                });
              },
              title: `${route.params.name}:设备`,
            });
            reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
            break;
          case '通知中心':
            if (route.params.paramsId) {
              openDrawer(true, {
                entityType: ENTITY_TYPE.DEVICE,
                entityId: route.params.paramsId,
                title: route.params.entityName,
                api: getDeviceInfo,
                detailSchema: detailSchema,
                params: route.params.paramsId,
              });
              setProps({
                api: getEntityDeviceList,
                beforeFetch: (val) => {
                  return getParams(val);
                },
              });
              reload({
                searchInfo: { textSearch: route.params.entityName },
                sortInfo: { field: 'createdTime', order: 'DESC' },
              });
            }
            break;
          case '首页':
            setProps({
              api: getEntityDeviceList,
              beforeFetch: (val) => {
                return getParams(val);
              },
            });
            reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
            openAddModal(true, 'test');
            break;
        }
      } else {
        setProps({
          api: getEntityDeviceList,
          beforeFetch: (val) => {
            return getParams(val);
          },
        });
        reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
      }
    } else if (roleList.includes(RoleEnum.CUSTOMER_USER)) {
      setProps({
        api: getCustomerEntityDeviceList,
        beforeFetch: (val) => {
          return Object.assign(getParams(val), { customerId: customerId });
        },
      });
      reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
    }
  });
</script>
